iT邦幫忙

2023 iThome 鐵人賽

DAY 7
1

雖然在前往獨角獸的路上很忙,但是絕對不能少的就是測試。
好的測試可以讓你開發中,減少重工浪費時間的機率,也可以讓整個 continuous delivery 的機制更多了一點的信心

而且在開發的過程中,可以讓測試案例幫助釐清功能的驗證同時,也可以更快速的修正,提早搶先在前端串接前發現問題並且修正。

所以我選用了一個目前社群討論熱度高,且使用上友善很多的 PEST

官方有寫一篇簡短的介紹可以看看這個套件的優勢

動手時間

以下是我針對開發 API 同時,先行設定好的幾個測試案例

取得 Channel 清單

describe('ChannelApi', function () {
    it('should be able to get a list of channels', function () {
        $response = $this->get('/api/channels');

        $this->assertEquals(200, $response->getStatusCode());
        $this->assertJsonResponse($response);
        $this->assertCount(5, $response->json());
    });
});

取得今日最新十個有新增 Episode 的 channel

describe('ChannelApi', function () {
    it('should be able to get the latest 10 channels with new episodes today', function () {
        $response = $this->get('/api/channels/latest');

        $this->assertEquals(200, $response->getStatusCode());
        $this->assertJsonResponse($response);
        $this->assertCount(10, $response->json());
    });
});

取得今日最多人 save Episode 的 channel

describe('ChannelApi', function () {
    it('should be able to get the channel with the most saved episodes today', function () {
        $response = $this->get('/api/channels/most-saved');

        $this->assertEquals(200, $response->getStatusCode());
        $this->assertJsonResponse($response);
        $this->assertEquals(1, $response->json()['id']);
        $this->assertEquals(10, $response->json()['episodes_count']);
    });
});

取得 Episode by id

describe('EpisodeApi', function () {
    it('should be able to get an episode by its ID', function () {
        $response = $this->get('/api/episodes/EXnf2B');

        $this->assertEquals(200, $response->getStatusCode());
        $this->assertJsonResponse($response);
        $this->assertEquals('http://localhost:8080/episode-1.mp4', $response->json()['guid']);
        $this->assertEquals('Episode 1', $response->json()['title']);
    });
});

取得今日最多人 save 的 Episode

describe('EpisodeApi', function () {
    it('should be able to get the episode with the most saves today', function () {
        $response = $this->get('/api/episodes/most-saved');

        $this->assertEquals(200, $response->getStatusCode());
        $this->assertJsonResponse($response);
        $this->assertEquals(1, $response->json()['id']);
        $this->assertEquals(10, $response->json()['saves_count']);
    });
});

以下是針對資料庫的讀寫寫的測試

use App\Models\Channel;
use Illuminate\Foundation\Testing\RefreshDatabase;

uses(Tests\TestCase::class, RefreshDatabase::class);

it('does not create a channel without a name field', function () {
    $response = $this->postJson('/api/channels', []);
    $response->assertStatus(422);
});

it('can create a channel', function () {
    $attributes = Channel::factory()->raw();
    $response = $this->postJson('/api/channels', $attributes);
    $response->assertStatus(201);
    $this->assertDatabaseHas('channels', $attributes);
});

it('can fetch a channel', function () {
    $channel = Channel::factory()->create();

    $response = $this->getJson("/api/channels/{$channel->id}");

    $data = [
        'channel' => [
            'id' => $channel->id,
            'country' => $channel->country,
            'cover_image' => $channel->cover_image,
            'title' => $channel->title,
            'slug' => $channel->slug,
            'description' => $channel->description,
        ]
    ];

    $response->assertStatus(200)->assertJson($data);
});

it('can update a channel', function () {
    $channel = Channel::factory()->create();
    $updatedChannel = ['id' => $channel->id];
    $response = $this->putJson("/api/channels/{$channel->id}", $updatedChannel);
    $response->assertStatus(200);
    $this->assertDatabaseHas('channels', $updatedChannel);
});

it('can delete a channel', function () {
    $channel = Channel::factory()->create();
    $response = $this->deleteJson("/api/channels/{$channel->id}");
    $response->assertStatus(200);
    $this->assertCount(0, Channel::all());
});

執行結果

以下是測試失敗時
test failed

這是測試都成功時
test ok

你以為只是在開發中幫 API 除錯,其實不知不覺中就已經把測試完成了呢!

提供一個給你相較於 Postman 之類的 API test client,已經整合在專案中的最佳選擇。

本次使用到的工具

  • Laravel + PHP 8.2
  • PEST

Reference

Notice

以上是這次實作的紀錄,如果有哪個部分需要解釋的部分,可以在留言處留下問題,我會盡量補充。


上一篇
#5 API Service 的第三步: 萬事起頭難,但是很重要的資料庫規劃
下一篇
#7 你其實不需要在 Laravel 使用 Repository Pattern (1/2)
系列文
Laravel 擴展宇宙:從 1 到 100 十倍速打造產品獨角獸30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言